package com.interest.web.controller.outer;

import com.alibaba.fastjson2.JSONObject;
import com.interest.business.domain.vo.CouponReceiveVo;
import com.interest.business.domain.vo.UserCouponVo;
import com.interest.business.outer.request.SmsCodeValidateBean;
import com.interest.business.outer.request.SmsSendBean;
import com.interest.business.service.IInterestRedeemCodeService;
import com.interest.business.utils.SmsService;
import com.interest.common.core.domain.AjaxResult;
import com.interest.common.core.redis.RedisCache;
import com.interest.common.exception.ServiceException;
import com.interest.common.utils.DateUtils;
import com.interest.common.utils.ServletUtils;
import com.interest.common.utils.StringUtils;
import com.interest.framework.web.service.TokenService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * H5页面API
 */
@RestController
@RequestMapping("/h5")
public class H5Api {

    private static final Logger LOGGER = LoggerFactory.getLogger(H5Api.class);

    @Autowired
    SmsService smsService;
    @Autowired
    RedisCache redisCache;
    @Autowired
    TokenService tokenService;

    @Autowired
    IInterestRedeemCodeService interestRedeemCodeService;

    private static final String H5_CODE_PREFIX="H5:CODE:";
    private static final String H5_TOKEN_PREFIX="H5:TOKEN:";
    /**
     * 发送短信
     * @return
     */
    @PostMapping("/sendSms")
    public AjaxResult sendSms(@RequestBody SmsSendBean smsSendBean){
        String phoneNumber = smsSendBean.getPhoneNumber();
        String codeValue = redisCache.getCacheObject(H5_CODE_PREFIX+phoneNumber);
        if(StringUtils.isNotEmpty(codeValue)){
            return AjaxResult.error("五分钟内，请勿重复发送");
        }
        if(StringUtils.isEmpty(phoneNumber)){
            return AjaxResult.error("手机号码不能为空");
        }
        if(!isPhoneNumber(phoneNumber)){
            return AjaxResult.error("手机号码格式错误");
        }
        String code = genCode();
        try {
            JSONObject result = smsService.sendSmsCode(phoneNumber,code);
            if(!StringUtils.equals(result.getString("code"),"OK")){
                return AjaxResult.error("短信发送失败");
            }
            redisCache.setCacheObject(H5_CODE_PREFIX+phoneNumber,code,5, TimeUnit.MINUTES);
            return AjaxResult.success();
        } catch (Exception e) {
            LOGGER.error("发送短信失败：",e);
            return AjaxResult.error("短信发送失败");
        }
    }

    /**
     * 校验验证码
     * @return
     */
    @PostMapping("/validateSmsCode")
    public AjaxResult validateSmsCode(@RequestBody SmsCodeValidateBean smsCodeValidateBean){
        String code = redisCache.getCacheObject(H5_CODE_PREFIX+smsCodeValidateBean.getPhoneNumber());
        if(StringUtils.isEmpty(code)){
            return AjaxResult.error(901,"验证码已过期，请重新获取");
        }
        if(!StringUtils.equals(code,smsCodeValidateBean.getCode())){
            return AjaxResult.error("验证码有误，请重新输入");
        }
        Map<String,Object> data = new HashMap<>();
        data.put("phoneNumber",smsCodeValidateBean.getPhoneNumber());
        String token = tokenService.createToken(data);
        redisCache.setCacheObject(H5_TOKEN_PREFIX+token,smsCodeValidateBean.getPhoneNumber(),7,TimeUnit.DAYS);
        return AjaxResult.success("验证通过",token);
    }

    /**
     * 获取兑换码列表
     */
    @GetMapping("/queryCouponList")
    public AjaxResult queryCouponList(){
        checkToken();
        String token = ServletUtils.getRequest().getHeader("token");
        String phoneNumber = redisCache.getCacheObject(H5_TOKEN_PREFIX+token);
        //根据手机号查询兑换码
        Date now = DateUtils.getNowDate();
        List<UserCouponVo> couponVos =  interestRedeemCodeService.selectUserCoupons(phoneNumber);
        couponVos.forEach(item->{
            if(now.after(item.getStartTime()) && now.before(item.getEndTime())){
                item.setStatus("0");
            }else{
                item.setStatus("1");
            }
        });
        return AjaxResult.success(couponVos);
    }

    /**
     * 领取优惠券
     * @return
     */
    @PostMapping("/receiveCoupon")
    public AjaxResult receiveCoupon(@RequestBody CouponReceiveVo receiveVo){
        checkToken();
        String token = ServletUtils.getRequest().getHeader("token");
        String phoneNumber = redisCache.getCacheObject(H5_TOKEN_PREFIX+token);
        receiveVo.setPhoneNumber(phoneNumber);
        interestRedeemCodeService.receiveCoupon(receiveVo);
        return AjaxResult.success();
    }

    /**
     * 退出登录
     * @return
     */
    @PostMapping("/logout")
    public AjaxResult logout(){
        String token = ServletUtils.getRequest().getHeader("token");
        if(StringUtils.isNotEmpty(token)){
            redisCache.deleteObject(H5_TOKEN_PREFIX+token);
        }
        return AjaxResult.success();
    }


    public static String genCode(){
        Random random = new Random();
        return ""+(random.nextInt(9000)+1000);
    }

    public static boolean isPhoneNumber(String phoneNumber){
        String phoneRegex = "^1[3-9]\\d{9}$";
        return phoneNumber.matches(phoneRegex);
    }

    private void checkToken() {
        String token = ServletUtils.getRequest().getHeader("token");
        if (StringUtils.isEmpty(token)) {
            throw new ServiceException("参数【TOKEN】为空，请重新登录!",999);
        }
        token = redisCache.getCacheObject(H5_TOKEN_PREFIX+token);
        if (StringUtils.isEmpty(token)) {
            throw new ServiceException("【TOKEN】已过期，请重新登录!", 999);
        }
    }
}
